package com.hqd.jjvm.rtda;

import com.hqd.jjvm.rtda.heap.JMethod;
import lombok.Getter;
import lombok.Setter;

import java.util.concurrent.atomic.AtomicInteger;

@Getter
@Setter
public class JThread {
    private AtomicInteger nextPc;
    private JvmStack jvmStack;

    public JThread(JMethod jMethod) {
        this.nextPc = new AtomicInteger(0);
        this.jvmStack = new JvmStack(jMethod);
    }

    public void pushFrame(StackFrame stackFrame) {
        recordCurrentStackStatus(stackFrame);

    }

    public StackFrame createStackFrame(JMethod jMethod) {
        StackFrame newFrame = new StackFrame(jMethod);
        for (int i = jMethod.getArgSlotCount() - 1; i >= 0; i--) {
            Object val = getJvmStack().popOperandStackVal();
            if (val instanceof Double || val instanceof Long) {
                i--;
            }
            newFrame.getLocalVars().setVal(i, val);
        }
        recordCurrentStackStatus(newFrame);
        return newFrame;
    }

    private void recordCurrentStackStatus(StackFrame newFrame) {
        /**
         * 记录当前方法返回地址
         */
        getJvmStack().getTop().setReturnAddress(getNextPc());
        getJvmStack().push(newFrame);
        setNextPc(new AtomicInteger(-1));
    }
}
